package client;

import client.skills.Skill;
import client.skills.SkillFactory;
import client.status.MonsterStatus;
import client.status.MonsterStatusEffect;
import constants.SkillConstants;
import constants.skills.*;
import server.MapleStatEffect;
import server.life.MapleMonster;
import server.maps.MapleMapObject;
import server.maps.MapleMapObjectType;
import server.maps.MapleSummon;
import server.skill.MapleForceAtom;
import server.skill.MapleForceAtomFactory;
import tools.MaplePacketCreator;
import tools.Randomizer;
import tools.packet.BuffPacket;
import tools.packet.EffectPacket;
import tools.packet.ForcePacket;
import tools.packet.SummonPacket;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class PlayerSkillHandler {
    //超能力者 心灵传动
    public static void handlerKSTelekinesis(MapleCharacter player, int oid) {
        Skill skill = SkillFactory.getSkill(超能力者.心灵传动);
        int skilllevel = player.getSkillLevel(超能力者.心灵传动);
        if (skilllevel > 0) {
            MapleStatEffect effect = skill.getEffect(skilllevel);
            if (effect != null && effect.makeChanceResult()) {
                player.getSpecialStat().gainCardStack();
                player.getMap().broadcastMessage(ForcePacket.心灵传动攻击效果(player.getId(), oid, 超能力者.心灵传动, player.getSpecialStat().getCardStack()), player.getTruePosition());
            }
        }
    }
    /**
     * 唤灵
     * @param player
     * @param moboid
     * @param attackBoss
     */
    public static void handleDeathPact(MapleCharacter player, int moboid, boolean attackBoss) {
        if (player.getBuffStatValueHolder(MapleBuffStat.死亡契约) == null) {
            return;
        }
        int[] skills_ = {唤灵斗师.死亡契约3, 唤灵斗师.死亡契约2, 唤灵斗师.死亡契约, 唤灵斗师.死亡};
        MapleStatEffect effect = null;
        for (int skillid_ : skills_) {
            if (player.getSkillLevel(skillid_) > 0) {
                effect = SkillFactory.getSkill(skillid_).getEffect(1);
                break;
            }
        }
        MapleMonster mob = player.getMap().getMonsterByOid(moboid);
        if (effect == null || mob == null) {
            return;
        }
        MapleSummon summon = player.getSummonBySkill(effect.getSourceid());
        if (summon == null) {
            return;
        }
        int maxCount = effect.getX() - (player.hasBuffSkill(唤灵斗师.战斗大师) ? 3 : 0);
        int currentCount = player.getSpecialStat().getDeathPactCount();
        if (currentCount < maxCount) {
            player.getSpecialStat().setDeathPactCount(Math.min(currentCount + (attackBoss && mob.isBoss() ? 2 : 1), maxCount));
        } else {
            if (summon.checkLastAttackTime()) {
                player.getSpecialStat().setDeathPactCount(0);
                player.getMap().broadcastMessage(SummonPacket.summonSkillLink(player.getId(), summon.getObjectId()), player.getTruePosition());
            }
        }
        Map<MapleBuffStat, Integer> localstatups = Collections.singletonMap(MapleBuffStat.死亡契约, player.getSpecialStat().getDeathPactCount());
        player.setBuffedValue(MapleBuffStat.死亡契约, player.getSpecialStat().getDeathPactCount());
        player.getClient().announce(BuffPacket.giveSingleBuff(effect.getSourceid(), 0, localstatups, effect, player));
    }

    /*
     * 夜光黑暗祝福处理
     */
    public static void handleBlackBless(MapleCharacter player) {
        if (player.getLastBlessOfDarknessTime() == 0) {
            player.setLastBlessOfDarknessTime(System.currentTimeMillis());
        }
        Skill skill = SkillFactory.getSkill(夜光.黑暗祝福); //27100003 - 黑暗祝福 - 战斗中，如果一定时间内不受伤害，就会产生可以保护自己的暗黑球体。球体累积之后可以增加魔力，有球体的情况下受到伤害，则减少伤害值，同时减少1个球体。
        int skilllevel = player.getTotalSkillLevel(skill);
        if (skilllevel <= 0) {
            return;
        }
        MapleStatEffect effect = skill.getEffect(skilllevel);
        if (player.getStatForBuff(MapleBuffStat.黑暗祝福) == null) {
            effect.applyTo(player);
            return;
        }
        if (player.getLastBlessOfDarknessTime() + effect.getDuration() < System.currentTimeMillis()) {
            int count = player.getBuffedValue(MapleBuffStat.黑暗祝福);
            if (count < 3) {
                count++;
            }
            Map<MapleBuffStat, Integer> stat = Collections.singletonMap(MapleBuffStat.黑暗祝福, count);
            player.setBuffedValue(MapleBuffStat.黑暗祝福, count);
            player.getClient().announce(EffectPacket.showBlessOfDarkness(skill.getId()));
            player.getClient().announce(BuffPacket.giveSingleBuff(skill.getId(), 0, stat, effect, player));
            player.setLastBlessOfDarknessTime(System.currentTimeMillis());
        }
    }

    public static void handleBlackBlessLost(MapleCharacter player, int howmany) {
        Skill skill = SkillFactory.getSkill(夜光.黑暗祝福);
        if (player.getSkillLevel(skill) <= 0) {
            player.cancelEffectFromBuffStat(MapleBuffStat.黑暗祝福);
            return;
        }
        MapleStatEffect effect = player.getStatForBuff(MapleBuffStat.黑暗祝福);
        if (effect == null) {
            return;
        }
        player.setLastBlessOfDarknessTime(System.currentTimeMillis());
        int count = player.getBuffedValue(MapleBuffStat.黑暗祝福);
        count = count - howmany;
        if (count <= 0) {
            player.cancelEffectFromBuffStat(MapleBuffStat.黑暗祝福);
        } else {
            Map<MapleBuffStat, Integer> stat = Collections.singletonMap(MapleBuffStat.黑暗祝福, count);
            player.setBuffedValue(MapleBuffStat.黑暗祝福, count);
            player.getClient().announce(EffectPacket.showBlessOfDarkness(skill.getId()));
            player.getClient().announce(BuffPacket.giveBuff(skill.getId(), 0, stat, effect, player));
        }
    }
    /*
     * 夜光黑暗高潮处理
     */
    public static void handleDarkCrescendo(MapleCharacter player) {
        MapleStatEffect dkeffect = player.getStatForBuff(MapleBuffStat.黑暗高潮);
        if (dkeffect != null && dkeffect.getSourceid() == 夜光.黑暗高潮) { //27121005 - 黑暗高潮 - 在一定时间内，攻击技能每命中一次敌人，都会有一定概率提升攻击力。
            int orbcount = player.getBuffedValue(MapleBuffStat.黑暗高潮);
            Skill skill = SkillFactory.getSkill(夜光.黑暗高潮);
            if (player.getSkillLevel(skill) > 0) {
                MapleStatEffect effect = skill.getEffect(player.getTotalSkillLevel(skill));
                if (orbcount < effect.getX() && effect.makeChanceResult()) {
                    int neworbcount = orbcount + 1;
                    Map<MapleBuffStat, Integer> stat = Collections.singletonMap(MapleBuffStat.黑暗高潮, neworbcount);
                    player.setBuffedValue(MapleBuffStat.黑暗高潮, neworbcount);
                    int duration = effect.getDuration();
                    duration += (int) ((player.getBuffedStartTime(MapleBuffStat.黑暗高潮) - System.currentTimeMillis()));
                    player.getClient().announce(BuffPacket.giveBuff(skill.getId(), duration, stat, effect, player));
                }
            }
        }
    }

    /*
     * 更新夜光 光暗点数
     */
    public static void handleLuminous(MapleCharacter player, int skillId) {
        if (skillId == 夜光.记录) {
            player.removeCooldown(夜光.死亡之刃, true);
            player.removeCooldown(夜光.绝对死亡, true);
            SkillFactory.getSkill(夜光.平衡_光明).getEffect(1).applyTo(player);
            return;
        }
        int skillMode = SkillConstants.getLuminousSkillMode(skillId);

        if (skillMode < 0 || skillMode == 夜光.平衡_光明 || player.getSkillLevel(skillMode) <= 0) {
            return;
        }

        // 平衡状态不改变点数
        Integer buffvalue = player.getBuffedValue(MapleBuffStat.光暗转换);
        if (buffvalue != null && buffvalue == 2) {
            return;
        }

        int gauge;
        byte gaugetype = (byte) (skillMode == 夜光.太阳火焰 ? 1 : 2);
        int balanceid = -1;

        if (!player.hasBuffSkill(夜光.太阳火焰) && !player.hasBuffSkill(夜光.月蚀)) {
            int newskillid = gaugetype == 1 ? 夜光.月蚀 : 夜光.太阳火焰;
            SkillFactory.getSkill(newskillid).getEffect(1).applyTo(player);
            gauge = skillMode == 夜光.太阳火焰 ? 9999 : 1;
        } else {
            boolean isLightSkill = gaugetype == 1;
            boolean isLightMode = player.getBuffSource(MapleBuffStat.光暗转换) == 夜光.太阳火焰;
            boolean isApply = false;
            gauge = player.getSpecialStat().getDarkLight();
            MapleStatEffect effect = SkillFactory.getSkill(skillId).getEffect(player.getTotalSkillLevel(skillId));
            int gauge_val = (int) (effect.getGauge() * (((double) player.getStat().getGauge_x() / 100) + 1.0));
            if (gaugetype == 1 && isLightMode) {            //月蚀
                gauge = Math.min(9999, gauge + gauge_val);
                isApply = true;
            } else if (gaugetype == 2 && !isLightMode) {    //太阳
                gauge = Math.max(1, gauge - gauge_val);
                isApply = true;
            }

            if (isLightMode) {
                player.addHP(player.getStat().getMaxHp() / 100); //恢复1%的hp
            }

            if (gauge == 9999) {
                balanceid = 夜光.平衡_光明;
            } else if (gauge == 1) {
                balanceid = 夜光.平衡_黑暗;
            }

            if (isApply && balanceid > 0) {
                player.cancelBuffStats(MapleBuffStat.光暗转换);
                player.removeCooldown(夜光.死亡之刃, true);
                player.removeCooldown(夜光.绝对死亡, true);
                SkillFactory.getSkill(balanceid).getEffect(1).applyTo(player);
            }
        }
        //更新光暗点数
        player.getSpecialStat().setDarkLight(gauge);
        player.getClient().announce(BuffPacket.updateLuminousGauge(gauge, gaugetype));
    }
    /*
     * 处理刺客标记攻击怪物效果
     */
    public static void handleAssassinStack(MapleCharacter player, MapleMonster mob) {
        int[] skillid = {隐士.刺客标记, 隐士.隐士标记};
        for (int i : skillid) {
            MapleStatEffect effect = player.getSkillEffect(i);
            if (effect == null) {
                continue;
            }
            if (effect.makeChanceResult() && mob != null) {
                List<MapleMapObject> arrayList = player.getMap().getMapObjectsInRange(mob.getPosition(), 250000.0, Collections.singletonList(MapleMapObjectType.MONSTER));
                List<Integer> tomobids = new ArrayList<>();
                for (MapleMapObject mobj : arrayList) {
                    tomobids.add(mobj.getObjectId());
                }
                MapleForceAtom forceAtom = MapleForceAtomFactory.INSTANCE.createForceAtom(player, effect, mob.getObjectId(), tomobids, mob.getPosition());
                player.getMap().broadcastMessage(player, forceAtom.getPacket(), true);
                mob.removeEffect(player.getId(), effect.getSourceid());
            }
        }
    }

    public static void apply刺客标记(MapleCharacter player, MapleMonster monster) {
        MapleStatEffect effect;
        Skill aq2 = SkillFactory.getSkill(隐士.刺客标记);
        Skill aq3 = SkillFactory.getSkill(隐士.隐士标记);
        if (player.getTotalSkillLevel(aq3) > 0) {
            effect = aq3.getEffect(player.getTotalSkillLevel(aq3));
        } else if (player.getTotalSkillLevel(aq2) > 0) {
            effect = aq2.getEffect(player.getTotalSkillLevel(aq2));
        } else {
            return;
        }
        if (effect.makeChanceResult() && player.getStatForBuff(MapleBuffStat.刺客标记) != null) {
            monster.setmark(true);
            monster.applyStatus(new MonsterStatusEffect(MonsterStatus.MOB_STAT_Poison, 1, effect.getSourceid(), null, false));
        }
    }

    /*
     * 侠盗本能击杀点数
     */
    public static void handleKillSpreeGain(MapleCharacter player) {
        Skill skill = SkillFactory.getSkill(侠盗.侠盗本能);
        int skillLevel = player.getSkillLevel(skill);
        int killSpree = player.getBuffedIntValue(MapleBuffStat.击杀点数);
        if (skillLevel <= 0 || killSpree >= 5) {
            return;
        }
        if (Randomizer.nextInt(100) <= 20) {
            skill.getEffect(skillLevel).applyTo(player, true);
        }
    }
    public static void handle暴风灭世(MapleCharacter player, int oid) {
        MapleStatEffect effect = player.getStatForBuff(MapleBuffStat.暴风灭世);
        if (effect != null) {
            MapleMonster monster = player.getMap().getMonsterByOid(oid);
            if (effect.makeChanceResult() && monster != null && !monster.isFake()) {
                MapleForce force = new MapleForce(player.getId(), 风灵使者.暴风灭世, 0, MapleForceType.暴风灭世, (byte) 1, Collections.singletonList(oid), (byte) 1, effect.getBulletCount(), player.getMap(), player.isFacingLeft());
                player.send_other(force.writePacket(), true);
            }
        }
    }
    /*
     * 奇袭者元素雷电被动BUFF设置
     */
    public static void handle元素雷电(MapleCharacter player, int skillId) {
        //这几个技能是不加雷电次数的
        if (skillId == 奇袭者.疾风 || skillId == 奇袭者.毁灭 || skillId == 奇袭者.台风) {
            return;
        }
        Skill skill = SkillFactory.getSkill(奇袭者.元素_闪电);
        int skillLevel = player.getSkillLevel(skill);
        if (skillLevel <= 0 || player.getBuffedValue(MapleBuffStat.元素属性) == null) {
            return;
        }
        if (Randomizer.nextInt(100) <= player.getStat().raidenPorp) {
            skill.getEffect(skillLevel).applyTo(player, true);
        }
    }
    public static void handleCarteGain(MapleCharacter player, int moid, boolean is5th) {
        if (is5th) {
            Skill skill = SkillFactory.getSkill(幻影.小丑_1);
            if (skill != null && player.getSkillLevel(幻影.王牌) > 0) {
                MapleStatEffect effect = skill.getEffect(player.getSkillLevel(幻影.王牌));
                if (effect != null) {
                    MapleForceAtom forceAtom = MapleForceAtomFactory.INSTANCE.createForceAtom(player, effect, 0);
                    player.getSpecialStat().gainCardStack();
                    player.send(MaplePacketCreator.updateCardStack(player.getSpecialStat().getCardStack()));
                    player.send_other(forceAtom.getPacket(), true);
                }
            }
        } else {
            int[] arrn2 = new int[]{幻影.黑色秘卡, 幻影.卡片雪舞};
            final int maxCarte = (player.getSkillLevel(幻影.卡牌审判_高级) > 0) ? 40 : 20;
            for (int skillid : arrn2) {
                Skill skill = SkillFactory.getSkill(skillid);
                if (skill != null && player.getSkillLevel(skill) > 0) {
                    MapleStatEffect effect = skill.getEffect(player.getSkillLevel(skill));
                    if (effect.makeChanceResult() && Randomizer.nextInt(100) <= player.getStat().passive_sharpeye_rate()) {
                        MapleForceAtom forceAtom = MapleForceAtomFactory.INSTANCE.createForceAtom(player, effect, 0);
                        player.send(forceAtom.getPacket());
                        if (player.getCardStack() < maxCarte) {
                            player.getSpecialStat().gainCardStack();
                        }
                    }
                    player.send(MaplePacketCreator.updateCardStack(player.getSpecialStat().getCardStack()));
                }
            }
        }
    }
}
